home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
print
/
gsview10.zip
/
clip.c
next >
Wrap
C/C++ Source or Header
|
1993-08-05
|
38KB
|
1,425 lines
/*
* clip.c -- Clipboard and EPS operations for GSVIEW.EXE,
* a graphical interface for MS-Windows Ghostscript
* Copyright (C) 1993 Russell Lang
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Author: Russell Lang
* Internet: rjl@monu1.cc.monash.edu.au
*/
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <shellapi.h>
#include <mmsystem.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dir.h>
#include <io.h>
#define NeedFunctionPrototypes 1
#include "ps.h"
#include "gsview.h"
#include <time.h>
#define COPY_BUF_SIZE 16384u
/* Write data to file - blocks > 64k permitted */
long
hwrite(HFILE hf, const void _huge *hpvBuffer, long cbBuffer)
{
DWORD count;
long written, done;
char _huge *hp;
if (is_win31)
return _hwrite(hf, hpvBuffer, cbBuffer);
done = 0;
hp = (char _huge *)hpvBuffer;
while (cbBuffer > 0) {
count = min( min(32768UL, cbBuffer), (DWORD)(65536UL-OFFSETOF(hp)) );
written = _lwrite(hf, hp, (UINT)count);
if (written == (long)HFILE_ERROR)
return (long)HFILE_ERROR;
done += written;
cbBuffer -= written;
hp += written;
}
return done;
}
/* return number of bytes per line, rounded up to multiple of 4 bytes */
LONG
dib_bytewidth(LPBITMAPINFOHEADER pbmih)
{
return (((pbmih->biWidth * pbmih->biBitCount + 31) & ~31) >> 3);
}
/* return number of colors in color table */
UINT
dib_pal_colors(LPBITMAPINFOHEADER pbmih)
{
int bits_per_pixel = pbmih->biPlanes * pbmih->biBitCount;
if (bits_per_pixel != 24) {
if (pbmih->biSize == sizeof(BITMAPCOREHEADER)) {
return 1<<bits_per_pixel;
}
else {
return (pbmih->biClrUsed) ? (UINT)(pbmih->biClrUsed) : 1<<bits_per_pixel;
}
}
return 0;
}
/* copy a DIB from the clipboard to a file */
void
clip_to_file(void)
{
HGLOBAL hglobal;
LPBITMAPINFOHEADER pbmih;
BITMAPFILEHEADER bmfh;
UINT palcolors;
UINT palsize;
DWORD bitmap_size;
BYTE _huge *lpBits;
static char output[MAXSTR];
HFILE hfile;
if (!OpenClipboard(hwndimg)) {
play_sound(SOUND_ERROR);
return;
}
if (!IsClipboardFormatAvailable(CF_DIB)) {
CloseClipboard();
play_sound(SOUND_ERROR);
return;
}
hglobal = (HGLOBAL)GetClipboardData(CF_DIB);
pbmih = (LPBITMAPINFOHEADER)GlobalLock(hglobal);
palcolors = dib_pal_colors(pbmih);
if (pbmih->biSize == sizeof(BITMAPCOREHEADER))
palsize = palcolors * sizeof(RGBTRIPLE);
else
palsize = palcolors * sizeof(RGBQUAD);
bitmap_size = (DWORD)pbmih->biHeight * dib_bytewidth(pbmih);
bmfh.bfType = ('M'<<8) | 'B';
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + pbmih->biSize + palsize;
bmfh.bfSize = bmfh.bfOffBits + bitmap_size;
if ( getfilename(output, SAVE, FILTER_BMP, NULL, IDS_TOPICEDIT)
&& ((hfile = _lcreat(output, 0)) != HFILE_ERROR) ) {
hwrite(hfile, &bmfh, sizeof(BITMAPFILEHEADER));
hwrite(hfile, pbmih, pbmih->biSize + palsize);
lpBits = ((BYTE _huge *)pbmih) + pbmih->biSize + palsize;
hwrite(hfile, lpBits, bitmap_size);
_lclose(hfile);
}
GlobalUnlock(hglobal);
CloseClipboard();
}
/* convert bitmap (DIB or DDB) in clipboard to */
/* CF_DIB, CF_BITMAP and CF_PALETTE */
void
clip_convert(void)
{
if (!OpenClipboard(hwndimg)) {
play_sound(SOUND_ERROR);
return;
}
if (IsClipboardFormatAvailable(CF_DIB)) {
if (!IsClipboardFormatAvailable(CF_PALETTE))
clip_add_palette();
if (!IsClipboardFormatAvailable(CF_BITMAP))
clip_add_ddb();
}
else {
if (IsClipboardFormatAvailable(CF_BITMAP)) {
clip_add_dib();
if (!IsClipboardFormatAvailable(CF_PALETTE))
clip_add_palette();
}
else
play_sound(SOUND_ERROR);
}
CloseClipboard();
}
/* Read DIB from the clipboard, create PALETTE and add to clipboard */
void
clip_add_palette(void)
{
HGLOBAL hglobal;
LPBITMAPINFOHEADER pbmih;
UINT palcolors;
UINT palsize;
int i;
LPLOGPALETTE logpalette;
HPALETTE hpalette;
RGBQUAD FAR *prgbquad;
RGBTRIPLE FAR *prgbtriple;
if (!IsClipboardFormatAvailable(CF_DIB)) {
play_sound(SOUND_ERROR);
return;
}
hglobal = (HGLOBAL)GetClipboardData(CF_DIB);
pbmih = (LPBITMAPINFOHEADER)GlobalLock(hglobal);
palcolors = dib_pal_colors(pbmih);
if (pbmih->biSize == sizeof(BITMAPCOREHEADER))
palsize = palcolors * sizeof(RGBTRIPLE);
else
palsize = palcolors * sizeof(RGBQUAD);
hpalette = (HPALETTE)NULL;
if (palsize) {
/* create palette to match DIB */
logpalette = (LPLOGPALETTE) malloc( sizeof(LOGPALETTE) +
palcolors * sizeof(PALETTEENTRY) );
if (logpalette == (LPLOGPALETTE)NULL) {
GlobalUnlock(hglobal);
play_sound(SOUND_ERROR);
return;
}
logpalette->palVersion = 0x300;
logpalette->palNumEntries = palcolors;
prgbquad = (RGBQUAD FAR *)(((BYTE _huge *)pbmih) + pbmih->biSize);
if (pbmih->biSize == sizeof(BITMAPCOREHEADER)) {
/* OS2 format */
prgbtriple = (RGBTRIPLE FAR *)prgbquad;
for (i=0; i<palcolors; i++) {
logpalette->palPalEntry[i].peFlags = 0;
logpalette->palPalEntry[i].peRed = prgbtriple[i].rgbtRed;
logpalette->palPalEntry[i].peGreen = prgbtriple[i].rgbtGreen;
logpalette->palPalEntry[i].peBlue = prgbtriple[i].rgbtBlue;
}
}
else {
/* Windows Format */
for (i=0; i<palcolors; i++) {
logpalette->palPalEntry[i].peFlags = 0;
logpalette->palPalEntry[i].peRed = prgbquad[i].rgbRed;
logpalette->palPalEntry[i].peGreen = prgbquad[i].rgbGreen;
logpalette->palPalEntry[i].peBlue = prgbquad[i].rgbBlue;
}
}
hpalette = CreatePalette(logpalette);
free((void *)logpalette);
SetClipboardData(CF_PALETTE, hpalette);
}
GlobalUnlock(hglobal);
}
/* Read DIB from the clipboard, convert to DDB and add to clipboard */
void
clip_add_ddb(void)
{
HGLOBAL hglobal;
LPBITMAPINFOHEADER pbmih;
UINT palcolors;
UINT palsize;
HPALETTE hpalette;
HDC hdc;
HBITMAP hbitmap;
hglobal = (HGLOBAL)GetClipboardData(CF_DIB);
pbmih = (LPBITMAPINFOHEADER)GlobalLock(hglobal);
palcolors = dib_pal_colors(pbmih);
if (pbmih->biSize == sizeof(BITMAPCOREHEADER))
palsize = palcolors * sizeof(RGBTRIPLE);
else
palsize = palcolors * sizeof(RGBQUAD);
hdc = GetDC(hwndimg);
hpalette = GetClipboardData(CF_PALETTE);
if (hpalette) {
SelectPalette(hdc,hpalette,NULL);
RealizePalette(hdc);
}
hbitmap = CreateDIBitmap(hdc, pbmih, CBM_INIT,
((BYTE _huge *)pbmih) + pbmih->biSize + palsize,
(LPBITMAPINFO)pbmih, DIB_RGB_COLORS);
ReleaseDC(hwndimg, hdc);
GlobalUnlock(hglobal);
SetClipboardData(CF_BITMAP, hbitmap);
}
/* make a DIB from a BITMAP in the clipboard */
/* GetDIBits won't work for 4 plane or 4 bit/pixel bitmaps */
/* clipboard must be open */
HGLOBAL
make_dib(void)
{
LPBITMAPINFOHEADER pbmih;
LPBITMAPINFO pbmi;
BYTE FAR *lpBits;
HBITMAP hbitmap;
UINT palcolors;
UINT palsize;
UINT byte_width;
DWORD bitmap_size;
HGLOBAL hglobal;
HDC hdc;
HDC hdc_bit;
BITMAP bm;
PALETTEENTRY *pe;
int i;
hbitmap = GetClipboardData(CF_BITMAP);
hdc = GetDC((HWND)NULL);
hdc_bit = CreateCompatibleDC(hdc);
ReleaseDC((HWND)NULL,hdc);
GetObject(hbitmap, sizeof(BITMAP), &bm);
if (bm.bmPlanes == 4) {
HBITMAP hbitmap_new, hbitmap_old;
HDC hdc_new;
/